<?php

/**
 * Services are globally registered in this file
 */
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Volt as VoltEngine;
use Phalcon\DI\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
use Phalcon\Session\Adapter\Files as SessionAdapter;
use Phalcon\Config\Adapter\Ini;
use Phalcon\Flash\Session as FlashSession;
use Phalcon\Flash\Direct as FlashDirect;
use Phalcon\Loader;
use Phalcon\Events\Manager as EventsManager;
use Registro\Auth\Auth;
use Registro\Acl\Acl;
use Registro\Common\Plugins\SecurityPlugin;
use Registro\Plugins\RouteNotFoundPlugin;
// Db Debug
use Phalcon\Logger;
use Phalcon\Logger\Adapter\File as FileLogger;

/**
 * Defining global constants
 */
$constants = new Ini( __DIR__ . '/constants.ini' );

foreach( $constants->globals as $key => $value ){
    define( strtoupper( $key ), $value );
}

/**
 * Read configuration
 */
$config = new Ini( __DIR__ . '/config.ini' );

$loader = new Loader();

$loader->registerNamespaces(
        [
            'Registro' => '/vagrant/www/registro/apps/library/',
            'Registro\Models' => $config->application->modelsDir,
            'Registro\Common' => $config->application->commonDir,
            'Registro\Plugins' => $config->application->pluginsDir,
            'Registro\Models\Helpers' => $config->application->modelsDir . '/Helpers',
        ]
 )->register();

/**
 * The FactoryDefault Dependency Injector automatically registers the right services to provide a full stack framework
 */
$di = new FactoryDefault();

/**
 * Database connection is created based in the parameters defined in the configuration file
 */
$di->set( 'db', function () use ( $config ){
    $eventsManager = new EventsManager();
    $logger = new FileLogger( '../apps/logs/db.log' );

    //Listen all the database events
    $eventsManager->attach( 'db', function($event, $connection) use ($logger){
        if( $event->getType() == 'beforeQuery' )
        {
            $logger->log( $connection->getSQLStatement(), Logger::INFO );
        }
    } );
    $connection = new DbAdapter( array(
        "host" => $config->database->host,
        "username" => $config->database->username,
        "password" => $config->database->password,
        "dbname" => $config->database->dbname//,
            //"charset" => $config->database->charset
            ) );
    //Assign the eventsManager to the db adapter instance
    $connection->setEventsManager( $eventsManager );
    return $connection;

//    return new DbAdapter( array(
//        "host" => $config->database->host,
//        "username" => $config->database->username,
//        "password" => $config->database->password,
//        "dbname" => $config->database->dbname//,
//            //"charset" => $config->database->charset
//            ) );
} );

/**
 * Registering a router
 */
$di->set( 'router', function (){
    return require 'services/router.php';
} );


/**
 * The URL component is used to generate all kinds of URLs in the application
 */
$di->set( 'url', function () use( $config ){
    $url = new UrlResolver();
    $url->setBaseUri( $config->application->baseUri );

    return $url;
} );

/**
 * Registering a global config service
 */
$di->set( 'globalConfig', function () use( $config ){
    return $config;
} );

/**
 * Starts the session the first time some component requests the session service
 */
$di->setShared( 'session', function (){
    $session = new SessionAdapter();
    $session->start();

    return $session;
} );

/**
 * Register the flash service with custom CSS classes
 */
$di->set( 'flashSession', function(){
    return new FlashSession( array(
        'error' => 'alert alert-danger',
        'success' => 'alert alert-success',
        'notice' => 'alert alert-info',
            ) );
} );
/**
 * Flash service with custom CSS classes
 */
$di->set( 'flash', function (){
    return new FlashDirect( array(
        'error' => 'alert alert-danger',
        'success' => 'alert alert-success',
        'notice' => 'alert alert-info',
        'warning' => 'alert alert-warning'
            ) );
} );
/**
 * Custom authentication component
 */
$di->set( 'auth', function (){
    return new Auth();
} );

/**
 * Crypt service
 */
$di->set( 'crypt', function () use ($config){
    $crypt = new Crypt();
    $crypt->setKey( $config->application->cryptSalt );
    return $crypt;
} );

/**
 * Access Control List
 */
$di->set( 'acl', function (){
    return new Acl();
} );
/**
 * We register the events manager
 */
$di->set( 'dispatcher', function() use ($di){

    $eventsManager = new EventsManager;

    /**
     * Check if the user is allowed to access certain action using the SecurityPlugin
     */
    $eventsManager->attach( 'dispatch:beforeExecuteRoute', new SecurityPlugin );

    /**
     * Handle exceptions and not-found exceptions using RouteNotFoundPlugin
     */
    $eventsManager->attach( 'dispatch:beforeException', new RouteNotFoundPlugin );

    $dispatcher = new Dispatcher;
    $dispatcher->setEventsManager( $eventsManager );

    return $dispatcher;
} );

/**
 * Setting up the view component using the array syntax in order to set the view path in every single module
 */
$di->set( 'view', function ()use ($config, $di){
    return require 'services/view.php';
} );

//$di->set( 'view', array(
//    'className' => 'Phalcon\Mvc\View',
//    'calls' => array(
//        array(
//            'method' => 'setLayoutsDir',
//            'arguments' => array(
//                array( 'type' => 'parameter', 'value' => $config->application->layoutDir ),
//            )
//        ),
//        array(
//            'method' => 'setTemplateAfter',
//            'arguments' => array(
//                array( 'type' => 'parameter', 'value' => 'main' ),
//            )
//        ),
//        array(
//            'method' => 'registerEngines',
//            'arguments' => array(
//                array( 'type' => 'parameter', 'value' => array(
//                        ".phtml" => 'volt'
//                    ) ),
//            )
//        )
//    ) ), true );

/**
 * Setting up volt
 */
$di->set( 'volt', function($view, $di){

    $volt = new VoltEngine( $view, $di );

    $volt->setOptions( array(
        'compiledPath' => APP_DIR . 'cache/volt/',
        'compiledSeparator' => '_',
        'compileAlways' => true
    ) );

    $compiler = $volt->getCompiler();
    $compiler->addFunction( 'is_a', 'is_a' );

    return $volt;
}, true );
